﻿using System;
using System.Threading;
using Microsoft.Practices.Unity;
using System.Windows;
using TciNewsReader_2014_04.Infrastructure;
using TciNewsReader_2014_04.Interfaces;
using TciNewsReader_2014_04.VmHelpers;
namespace TciNewsReader_2014_04
{
    public sealed partial class App : IDisposable
    {
        private readonly UnityContainer _container = new UnityContainer();
        private readonly SingleInstanceAssembly _singleInstanceAssembly;
        private WindowPositionSaver _windowPositionSaver;
        private MainWindow _mainWindow;
        private bool _disposed;
        public App()
        {
            Mutex mutex;
            _singleInstanceAssembly = new SingleInstanceAssembly(this, out mutex);
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            if (_singleInstanceAssembly.IsUniqueInstance)
            {
                UnityRegistration();
                _mainWindow = new MainWindow { DataContext = _container.Resolve(typeof(IViewModel)) };
                if (TciNewsReader_2014_04.Properties.Settings.Default.SaveAndRestoreWindowPosition)
                {
                    _windowPositionSaver = _container.Resolve<WindowPositionSaver>() as WindowPositionSaver;
                    _windowPositionSaver.RestoreWindowPosition(_mainWindow);
                }
                _mainWindow.Show();
            }
            else
            {
                _singleInstanceAssembly.CloseOtherInstance();
            }
        }
        protected override void OnExit(ExitEventArgs e)
        {
            if (_singleInstanceAssembly.IsUniqueInstance)
            {
                if(TciNewsReader_2014_04.Properties.Settings.Default.SaveAndRestoreWindowPosition)
                {
                    _windowPositionSaver.SavedWindowPosition(_mainWindow);
                }
                if (TciNewsReader_2014_04.Properties.Settings.Default.ShowExceptionsOnClose)
                {
                    ILogger logger = _container.Resolve<ILogger>();
                    if (logger.HasContent())
                    {
                        IConfirmations confirmations = _container.Resolve<IConfirmations>();
                        bool answer = confirmations.Confirm("Some exceptions were logged during this session.  Examine them (open Notepad)?");
                        if (answer)
                        {
                            logger.Show();
                        }
                    }
                }
            }
            base.OnExit(e);
        }
        private void UnityRegistration()
        {
            _container.RegisterType<IConfirmations, Confirmations>(new ContainerControlledLifetimeManager());
            _container.RegisterType<IExceptionHandler, ExceptionHandler>(new ContainerControlledLifetimeManager());
            _container.RegisterType<IPersistenceManager, PersistenceManager>(new ContainerControlledLifetimeManager());
            _container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());
            _container.RegisterType<IIncludeExclude, IncludeExcludeInitializer>();
            _container.RegisterType<IHelpAbout, HelpAboutInitializer>();
            _container.RegisterType<IErrorReport, ErrorReportInitializer>();
            _container.RegisterType<IFeedCrud, FeedCrudInitializer>();
            _container.RegisterType<IConfig, ConfigInitializer>();
            _container.RegisterType<IViewModel, ViewModel>(new ContainerControlledLifetimeManager());
            TaskRunner taskRunner = new TaskRunner(TciNewsReader_2014_04.Properties.Settings.Default.AsyncTasking);
            _container.RegisterInstance(typeof (TaskRunner), taskRunner);
        }
        public void Dispose()
        {
            Dispose(true);
            // ReSharper disable once GCSuppressFinalizeForTypeWithoutDestructor
            GC.SuppressFinalize(this);
        }
        private void Dispose(bool isDisposing)
        {
            if (_disposed) return;
            if (isDisposing)
            {
                _container.Dispose();
            }
            _disposed = true;
        }
    }
}
